﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using SDR = System.Drawing;
using System.Runtime.InteropServices;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Features2D;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using Emgu.CV.WPF;


using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.IO;
using Microsoft.Win32;
using System.Windows.Media.Imaging;

namespace jsmag
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        String input_folder_string, output_folder_string;
        List<Image<Gray, Byte>> oryginalImages;
        List<BitmapSource> oryginalImages_toDisplay;



        #region SURF
        #region SURF_results
        List<Result> SURF_results;
        MeanResult SURF_mean;
        #endregion

        #region SURF_param
        double SURF_hessianThreshold;
        int SURF_numberOfOctaves;
        int SURF_numberOfLayers;
        bool SURF_upright;
        #endregion

        #region SURF_functions
        private void makeSURF()
        {
            readSURFparam();
            Examinator_SURF eSURF = new Examinator_SURF();
            eSURF.SetSurfParameters(SURF_hessianThreshold, SURF_numberOfOctaves, SURF_numberOfLayers, SURF_upright);
            SURF_results = eSURF.RunSURF(oryginalImages);
            SURF_mean = countMeanRecord(SURF_results);

            presentSURF();
            printSURFresults();
        }

        private void readSURFparam()
        {
            SURF_hessianThreshold = Double.Parse(gui_surf_hessian_threshold_value.Text);
            SURF_numberOfOctaves = int.Parse(gui_surf_number_of_octaves.Text);
            SURF_numberOfLayers = int.Parse(gui_surf_number_of_layers.Text);
            if (gui_surf_desciptor_size.Text.Equals("64"))
            {
                SURF_upright = false;
            }
            else
            {
                SURF_upright = true;
            }
        }

        private void presentSURF()
        {
            //images
            gui_surf_image_12.Source = SURF_results[0].matchedImages_toDisplay;
            gui_surf_image_13.Source = SURF_results[1].matchedImages_toDisplay;
            gui_surf_image_14.Source = SURF_results[2].matchedImages_toDisplay;
            gui_surf_image_15.Source = SURF_results[3].matchedImages_toDisplay;
            gui_surf_image_16.Source = SURF_results[4].matchedImages_toDisplay;

            gui_surf_dopasowanie_czas_12.Content = SURF_results[0].matchingTime;
            gui_surf_dopasowanie_czas_13.Content = SURF_results[1].matchingTime;
            gui_surf_dopasowanie_czas_14.Content = SURF_results[2].matchingTime;
            gui_surf_dopasowanie_czas_15.Content = SURF_results[3].matchingTime;
            gui_surf_dopasowanie_czas_16.Content = SURF_results[4].matchingTime;

            gui_surf_dopasowanie_procent_12.Content = SURF_results[0].percentOfMatching;
            gui_surf_dopasowanie_procent_13.Content = SURF_results[1].percentOfMatching;
            gui_surf_dopasowanie_procent_14.Content = SURF_results[2].percentOfMatching;
            gui_surf_dopasowanie_procent_15.Content = SURF_results[3].percentOfMatching;
            gui_surf_dopasowanie_procent_16.Content = SURF_results[4].percentOfMatching;

            gui_surf_dopasowanie_ilosc_12.Content = SURF_results[0].numberOfMatchedFeatures;
            gui_surf_dopasowanie_ilosc_13.Content = SURF_results[1].numberOfMatchedFeatures;
            gui_surf_dopasowanie_ilosc_14.Content = SURF_results[2].numberOfMatchedFeatures;
            gui_surf_dopasowanie_ilosc_15.Content = SURF_results[3].numberOfMatchedFeatures;
            gui_surf_dopasowanie_ilosc_16.Content = SURF_results[4].numberOfMatchedFeatures;


            gui_surf_obrazek_1_czas_deskryptora.Content = SURF_results[0].firstImageDescriptorsCountingTime;
            gui_surf_obrazek_1_czas_na_ceche.Content = SURF_results[0].firstImageTimePer1Feature;
            gui_surf_obrazek_1_czas_wyszukania.Content = SURF_results[0].firstImageFeaturesFindingTime;
            gui_surf_obrazek_1_ilosc_cech.Content = SURF_results[0].firstImageNumberOfGeneratedFeatures;
            gui_surf_obrazek_1_czas_na_deskryptor.Content = SURF_results[0].firstImageTimePer1Descriptor;

            gui_surf_obrazek_2_czas_deskryptora.Content = SURF_results[0].secondImageDescriptorsCountingTime;
            gui_surf_obrazek_2_czas_na_ceche.Content = SURF_results[0].secondImageTimePer1Feature;
            gui_surf_obrazek_2_czas_wyszukania.Content = SURF_results[0].secondImageFeaturesFindingTime;
            gui_surf_obrazek_2_ilosc_cech.Content = SURF_results[0].secondImageNumberOfGeneratedFeatures;
            gui_surf_obrazek_2_czas_na_deskryptor.Content = SURF_results[0].secondImageTimePer1Descriptor;

            gui_surf_obrazek_3_czas_deskryptora.Content = SURF_results[1].secondImageDescriptorsCountingTime;
            gui_surf_obrazek_3_czas_na_ceche.Content = SURF_results[1].secondImageTimePer1Feature;
            gui_surf_obrazek_3_czas_wyszukania.Content = SURF_results[1].secondImageFeaturesFindingTime;
            gui_surf_obrazek_3_ilosc_cech.Content = SURF_results[1].secondImageNumberOfGeneratedFeatures;
            gui_surf_obrazek_3_czas_na_deskryptor.Content = SURF_results[1].secondImageTimePer1Descriptor;

            gui_surf_obrazek_4_czas_deskryptora.Content = SURF_results[2].secondImageDescriptorsCountingTime;
            gui_surf_obrazek_4_czas_na_ceche.Content = SURF_results[2].secondImageTimePer1Feature;
            gui_surf_obrazek_4_czas_wyszukania.Content = SURF_results[2].secondImageFeaturesFindingTime;
            gui_surf_obrazek_4_ilosc_cech.Content = SURF_results[2].secondImageNumberOfGeneratedFeatures;
            gui_surf_obrazek_4_czas_na_deskryptor.Content = SURF_results[2].secondImageTimePer1Descriptor;

            gui_surf_obrazek_5_czas_deskryptora.Content = SURF_results[3].secondImageDescriptorsCountingTime;
            gui_surf_obrazek_5_czas_na_ceche.Content = SURF_results[3].secondImageTimePer1Feature;
            gui_surf_obrazek_5_czas_wyszukania.Content = SURF_results[3].secondImageFeaturesFindingTime;
            gui_surf_obrazek_5_ilosc_cech.Content = SURF_results[3].secondImageNumberOfGeneratedFeatures;
            gui_surf_obrazek_5_czas_na_deskryptor.Content = SURF_results[3].secondImageTimePer1Descriptor;

            gui_surf_obrazek_6_czas_deskryptora.Content = SURF_results[4].secondImageDescriptorsCountingTime;
            gui_surf_obrazek_6_czas_na_ceche.Content = SURF_results[4].secondImageTimePer1Feature;
            gui_surf_obrazek_6_czas_wyszukania.Content = SURF_results[4].secondImageFeaturesFindingTime;
            gui_surf_obrazek_6_ilosc_cech.Content = SURF_results[4].secondImageNumberOfGeneratedFeatures;
            gui_surf_obrazek_6_czas_na_deskryptor.Content = SURF_results[4].secondImageTimePer1Descriptor;



            gui_surf_czas_wyszukania_ogol.Content = SURF_mean.ImageFeaturesFindingTime;

            gui_surf_czas_generowania_deskryptora.Content = SURF_mean.ImageDescriptorsCountingTime;

            gui_surf_ilosc_cech_ogol.Content = SURF_mean.ImageNumberOfGeneratedFeatures;

            gui_surf_czas_1_cecha_ogol.Content = SURF_mean.ImageTimePer1Feature;

            gui_surf_czas_1_deskryptor_ogol.Content = SURF_mean.ImageTimePer1Descriptor;



            gui_surf_ilosc_dopasowan_ogol.Content = SURF_mean.numberOfMatchedFeatures;
            gui_surf_czas_dopasowania_ogol.Content = SURF_mean.matchingTime;
            gui_surf_procent_dopasowan_ogol.Content = SURF_mean.percentOfMatching;



        }

        private void printSURFresults()
        {
        }
        #endregion
        #endregion

        #region common

        public MainWindow()
        {
            InitializeComponent();
        }

        MeanResult countMeanRecord(List<Result> r)
        {
            Result mean = new Result();
            MeanResult meanRecord = new MeanResult();
            foreach (Result record in r)
            {
                mean.firstImageFeaturesFindingTime += record.firstImageFeaturesFindingTime;
                mean.secondImageFeaturesFindingTime += record.secondImageFeaturesFindingTime;

                mean.firstImageDescriptorsCountingTime += record.firstImageDescriptorsCountingTime;
                mean.secondImageDescriptorsCountingTime += record.secondImageDescriptorsCountingTime;

                mean.firstImageNumberOfGeneratedFeatures += record.firstImageNumberOfGeneratedFeatures;
                mean.secondImageNumberOfGeneratedFeatures += record.secondImageNumberOfGeneratedFeatures;

                mean.firstImageTimePer1Feature += record.firstImageTimePer1Feature;
                mean.secondImageTimePer1Feature += record.secondImageTimePer1Feature;

                mean.firstImageTimePer1Descriptor += record.firstImageTimePer1Descriptor;
                mean.secondImageTimePer1Descriptor += record.secondImageTimePer1Descriptor;



                mean.numberOfMatchedFeatures += record.numberOfMatchedFeatures;
                mean.matchingTime += record.matchingTime;
                mean.percentOfMatching += record.percentOfMatching;
            }


            mean.secondImageFeaturesFindingTime = mean.secondImageFeaturesFindingTime + r[0].firstImageFeaturesFindingTime;
            meanRecord.ImageFeaturesFindingTime = mean.secondImageFeaturesFindingTime / 6;

            mean.secondImageDescriptorsCountingTime = mean.secondImageDescriptorsCountingTime + r[0].firstImageDescriptorsCountingTime;
            meanRecord.ImageDescriptorsCountingTime = mean.secondImageDescriptorsCountingTime / 6;

            mean.secondImageNumberOfGeneratedFeatures = mean.secondImageNumberOfGeneratedFeatures + r[0].firstImageNumberOfGeneratedFeatures;
            meanRecord.ImageNumberOfGeneratedFeatures = mean.secondImageNumberOfGeneratedFeatures / 6;

            mean.secondImageTimePer1Feature = mean.secondImageTimePer1Feature + r[0].firstImageTimePer1Feature;
            meanRecord.ImageTimePer1Feature = mean.secondImageTimePer1Feature / 6;

            mean.secondImageTimePer1Descriptor = mean.secondImageTimePer1Descriptor + r[0].firstImageTimePer1Descriptor;
            meanRecord.ImageTimePer1Descriptor = mean.secondImageTimePer1Descriptor / 6;

            mean.numberOfMatchedFeatures = mean.numberOfMatchedFeatures / 6;
            meanRecord.numberOfMatchedFeatures = mean.numberOfMatchedFeatures;
            mean.matchingTime = mean.matchingTime / 6;
            meanRecord.matchingTime = mean.matchingTime;
            mean.percentOfMatching = mean.percentOfMatching / 6;
            meanRecord.percentOfMatching = mean.percentOfMatching;

            return meanRecord;
        }
        #endregion

        #region gui_tab_start
        #region start_checkbox
        private void checkBox_SURF_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void checkBox_SIFT_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void checkBox_STAR_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void checkBox_FAST_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void checkBox_ORB_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void checkBox_STARBUG_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void checkBox_SURF_Unchecked(object sender, RoutedEventArgs e)
        {

        }

        private void checkBox_SIFT_Unchecked(object sender, RoutedEventArgs e)
        {

        }

        private void checkBox_STAR_Unchecked(object sender, RoutedEventArgs e)
        {

        }

        private void checkBox_ORB_Unchecked(object sender, RoutedEventArgs e)
        {

        }

        private void checkBox_STARBUG_Unchecked(object sender, RoutedEventArgs e)
        {

        }

        private void checkBox_FAST_Unchecked(object sender, RoutedEventArgs e)
        {

        }
        #endregion

        #region button_actions

        private void gui_start_start_button_Click(object sender, RoutedEventArgs e)
        {
            //załadowanie oryginalnych obrazow           
            oryginalImages = ImagesLoader.loadImages(input_folder_string);
            //przetworzenie obrazow oryginalych na forme dajacą się wyswietlać
            oryginalImages_toDisplay = BitmapSourceConvert.ToBitmapSourceFromImagesList(oryginalImages);
            //wyswietlenie oryginalnych obrazów
            pierdolonaLista.DataContext = oryginalImages_toDisplay;

            // makeSURF();
            makeSIFT();

        }

        private void gui_start_input_button_Click(object sender, RoutedEventArgs e)
        {
            gui_start_input_string.Text = ImagesLoader.loadFolderName(true);
            input_folder_string = gui_start_input_string.Text;
        }

        #endregion
        #endregion



        #region SIFT
        #region SIFT_results
        List<Result> SIFT_results;
        MeanResult SIFT_mean;
        #endregion

        #region SIFT_param
        int SIFT_nFeatures;
        int SIFT_nOctaveLayers;
        double SIFT_contrastThreshold;
        double SIFT_edgeThreshold;
        double SIFT_sigma;
        #endregion

        private void makeSIFT()
        {
            readSIFTparam();
            Examinator_SIFT eSIFT = new Examinator_SIFT();
            eSIFT.SetSIFTParameters(SIFT_nFeatures,SIFT_nOctaveLayers,SIFT_contrastThreshold,SIFT_edgeThreshold,SIFT_sigma);
            SIFT_results = eSIFT.RunSIFT(oryginalImages);
            SIFT_mean = countMeanRecord(SIFT_results);

            presentSIFT();
            printSIFTresults();
        }

        private void readSIFTparam()
        {
            SIFT_nFeatures = int.Parse(gui_sift_nFeatures.Text);
            SIFT_nOctaveLayers = int.Parse(gui_sift_number_of_layers.Text);
            SIFT_contrastThreshold = Double.Parse(gui_sift_contrast_threshold.Text);
            SIFT_edgeThreshold = Double.Parse(gui_sift_edge_threshold.Text);
            SIFT_sigma = Double.Parse(gui_sift_sigma.Text);
        }

        private void presentSIFT()
        {
            //images
            gui_sift_image_12.Source = SIFT_results[0].matchedImages_toDisplay;
            gui_sift_image_13.Source = SIFT_results[1].matchedImages_toDisplay;
            gui_sift_image_14.Source = SIFT_results[2].matchedImages_toDisplay;
            gui_sift_image_15.Source = SIFT_results[3].matchedImages_toDisplay;
            gui_sift_image_16.Source = SIFT_results[4].matchedImages_toDisplay;

            gui_sift_dopasowanie_czas_12.Content = SIFT_results[0].matchingTime;
            gui_sift_dopasowanie_czas_13.Content = SIFT_results[1].matchingTime;
            gui_sift_dopasowanie_czas_14.Content = SIFT_results[2].matchingTime;
            gui_sift_dopasowanie_czas_15.Content = SIFT_results[3].matchingTime;
            gui_sift_dopasowanie_czas_16.Content = SIFT_results[4].matchingTime;

            gui_sift_dopasowanie_procent_12.Content = SIFT_results[0].percentOfMatching;
            gui_sift_dopasowanie_procent_13.Content = SIFT_results[1].percentOfMatching;
            gui_sift_dopasowanie_procent_14.Content = SIFT_results[2].percentOfMatching;
            gui_sift_dopasowanie_procent_15.Content = SIFT_results[3].percentOfMatching;
            gui_sift_dopasowanie_procent_16.Content = SIFT_results[4].percentOfMatching;

            gui_sift_dopasowanie_ilosc_12.Content = SIFT_results[0].numberOfMatchedFeatures;
            gui_sift_dopasowanie_ilosc_13.Content = SIFT_results[1].numberOfMatchedFeatures;
            gui_sift_dopasowanie_ilosc_14.Content = SIFT_results[2].numberOfMatchedFeatures;
            gui_sift_dopasowanie_ilosc_15.Content = SIFT_results[3].numberOfMatchedFeatures;
            gui_sift_dopasowanie_ilosc_16.Content = SIFT_results[4].numberOfMatchedFeatures;


            gui_sift_obrazek_1_czas_deskryptora.Content = SIFT_results[0].firstImageDescriptorsCountingTime;
            gui_sift_obrazek_1_czas_na_ceche.Content = SIFT_results[0].firstImageTimePer1Feature;
            gui_sift_obrazek_1_czas_wyszukania.Content = SIFT_results[0].firstImageFeaturesFindingTime;
            gui_sift_obrazek_1_ilosc_cech.Content = SIFT_results[0].firstImageNumberOfGeneratedFeatures;
            gui_sift_obrazek_1_czas_na_deskryptor.Content = SIFT_results[0].firstImageTimePer1Descriptor;

            gui_sift_obrazek_2_czas_deskryptora.Content = SIFT_results[0].secondImageDescriptorsCountingTime;
            gui_sift_obrazek_2_czas_na_ceche.Content = SIFT_results[0].secondImageTimePer1Feature;
            gui_sift_obrazek_2_czas_wyszukania.Content = SIFT_results[0].secondImageFeaturesFindingTime;
            gui_sift_obrazek_2_ilosc_cech.Content = SIFT_results[0].secondImageNumberOfGeneratedFeatures;
            gui_sift_obrazek_2_czas_na_deskryptor.Content = SIFT_results[0].secondImageTimePer1Descriptor;

            gui_sift_obrazek_3_czas_deskryptora.Content = SIFT_results[1].secondImageDescriptorsCountingTime;
            gui_sift_obrazek_3_czas_na_ceche.Content = SIFT_results[1].secondImageTimePer1Feature;
            gui_sift_obrazek_3_czas_wyszukania.Content = SIFT_results[1].secondImageFeaturesFindingTime;
            gui_sift_obrazek_3_ilosc_cech.Content = SIFT_results[1].secondImageNumberOfGeneratedFeatures;
            gui_sift_obrazek_3_czas_na_deskryptor.Content = SIFT_results[1].secondImageTimePer1Descriptor;

            gui_sift_obrazek_4_czas_deskryptora.Content = SIFT_results[2].secondImageDescriptorsCountingTime;
            gui_sift_obrazek_4_czas_na_ceche.Content = SIFT_results[2].secondImageTimePer1Feature;
            gui_sift_obrazek_4_czas_wyszukania.Content = SIFT_results[2].secondImageFeaturesFindingTime;
            gui_sift_obrazek_4_ilosc_cech.Content = SIFT_results[2].secondImageNumberOfGeneratedFeatures;
            gui_sift_obrazek_4_czas_na_deskryptor.Content = SIFT_results[2].secondImageTimePer1Descriptor;

            gui_sift_obrazek_5_czas_deskryptora.Content = SIFT_results[3].secondImageDescriptorsCountingTime;
            gui_sift_obrazek_5_czas_na_ceche.Content = SIFT_results[3].secondImageTimePer1Feature;
            gui_sift_obrazek_5_czas_wyszukania.Content = SIFT_results[3].secondImageFeaturesFindingTime;
            gui_sift_obrazek_5_ilosc_cech.Content = SIFT_results[3].secondImageNumberOfGeneratedFeatures;
            gui_sift_obrazek_5_czas_na_deskryptor.Content = SIFT_results[3].secondImageTimePer1Descriptor;

            gui_sift_obrazek_6_czas_deskryptora.Content = SIFT_results[4].secondImageDescriptorsCountingTime;
            gui_sift_obrazek_6_czas_na_ceche.Content = SIFT_results[4].secondImageTimePer1Feature;
            gui_sift_obrazek_6_czas_wyszukania.Content = SIFT_results[4].secondImageFeaturesFindingTime;
            gui_sift_obrazek_6_ilosc_cech.Content = SIFT_results[4].secondImageNumberOfGeneratedFeatures;
            gui_sift_obrazek_6_czas_na_deskryptor.Content = SIFT_results[4].secondImageTimePer1Descriptor;



            gui_sift_czas_wyszukania_ogol.Content = SIFT_mean.ImageFeaturesFindingTime;

            gui_sift_czas_generowania_deskryptora.Content = SIFT_mean.ImageDescriptorsCountingTime;

            gui_sift_ilosc_cech_ogol.Content = SIFT_mean.ImageNumberOfGeneratedFeatures;

            gui_sift_czas_1_cecha_ogol.Content = SIFT_mean.ImageTimePer1Feature;

            gui_sift_czas_1_deskryptor_ogol.Content = SIFT_mean.ImageTimePer1Descriptor;



            gui_sift_ilosc_dopasowan_ogol.Content = SIFT_mean.numberOfMatchedFeatures;
            gui_sift_czas_dopasowania_ogol.Content = SIFT_mean.matchingTime;
            gui_sift_procent_dopasowan_ogol.Content = SIFT_mean.percentOfMatching;
        }

        private void printSIFTresults()
        {
        }

        #endregion

    }





}
